﻿using System.Xml.Linq;
using NUnit.Framework;

namespace NJabber.Stream.Elements
{
    [TestFixture]
    public class RosterItemElementTest : XmppStreamElementTestBase
    {
        private string itemName = "contact-name";
        private JID jid = "contact@domain.com";

        public RosterItemElementTest() : base("item", "", "")
        {
        }

        #region Write method tests

        [Test]
        public void Write_NotEmptyNameAttribute_CorrectlyWritesXml()
        {
            RosterItemElement itemElement = new RosterItemElement(itemName);
            XElement expectedElement = CreateRosterItemXElement(itemName, null, "");
            VerifyWriteOutput(expectedElement, itemElement);
        }

        [Test]
        public void Write_NotEmptyJidAttribute_CorrectlyWritesXml()
        {
            RosterItemElement itemElement = new RosterItemElement("", jid);
            XElement expectedElement = CreateRosterItemXElement("", jid, "");
            VerifyWriteOutput(expectedElement, itemElement);
        }

        [Test]
        public void Write_NotEmptyNameAndJidAttribute_CorrectlyWritesXml()
        {
            RosterItemElement itemElement = new RosterItemElement(itemName, jid);
            XElement expectedElement = CreateRosterItemXElement(itemName, jid, "");
            VerifyWriteOutput(expectedElement, itemElement);
        }

        [Test]
        public void Write_NotEmptySubscriptionAttribute_CorrectlyWritesXml()
        {
            RosterItemElement itemElement = new RosterItemElement(itemName, jid, "some-status");
            XElement expectedElement = CreateRosterItemXElement(itemName, jid, "some-status");
            VerifyWriteOutput(expectedElement, itemElement);
        }

        private XElement CreateRosterItemXElement(string itemName, JID itemJid, string subscriptionStatus)
        {
            XElement item = CreateXElement(Name);
            if (!string.IsNullOrEmpty(itemName)) item.SetAttributeValue("name", itemName);
            if (itemJid != null) item.SetAttributeValue("jid", itemJid);
            if (!string.IsNullOrEmpty(subscriptionStatus)) item.SetAttributeValue("subscription", subscriptionStatus);
            return item;
        }

        [Test]
        public void Write_NotEmptyGroupCollection_CorrectlyWritesXml()
        {
            string[] groups = { "group1", "group2", "group3" };
            RosterItemElement itemElement = new RosterItemElement(itemName, jid);
            XElement expectedElement = CreateRosterItemXElement(itemName, jid, groups);
            itemElement.AddGroups(groups);
            VerifyWriteOutput(expectedElement, itemElement);
        }

        private XElement CreateRosterItemXElement(string itemName, JID itemJid, params string[] groups)
        {
            XElement element = CreateRosterItemXElement(itemName, itemJid, "");
            foreach (string groupName in groups) element.Add(new XElement("group", groupName));
            return element;
        }

        #endregion

        #region Equals method tests

        [Test]
        public void Equals_SameNames_ReturnsTrue()
        {
            RosterItemElement rosterItem1 = new RosterItemElement("item");
            RosterItemElement rosterItem2 = new RosterItemElement("item");

            Assert.That(rosterItem1, Is.EqualTo(rosterItem2));
        }

        [Test]
        public void Equals_DifferentNames_ReturnsFalse()
        {
            RosterItemElement rosterItem1 = new RosterItemElement("bruce");
            RosterItemElement rosterItem2 = new RosterItemElement("marty");

            Assert.That(rosterItem1, Is.Not.EqualTo(rosterItem2));
        }

        [Test]
        public void Equals_SameJids_ReturnsTrue()
        {
            RosterItemElement rosterItem1 = new RosterItemElement("i", "mary@m.com");
            RosterItemElement rosterItem2 = new RosterItemElement("i", "mary@m.com");

            Assert.That(rosterItem1, Is.EqualTo(rosterItem2));
        }

        [Test]
        public void Equals_DifferentJids_ReturnsFalse()
        {
            RosterItemElement rosterItem1 = new RosterItemElement("a", "mary@m.com");
            RosterItemElement rosterItem2 = new RosterItemElement("a", "nancy@n.com");

            Assert.That(rosterItem1, Is.Not.EqualTo(rosterItem2));
        }

        [Test]
        public void Equals_SameGroupSet_ReturnsTrue()
        {
            RosterItemElement rosterItem1 = new RosterItemElement("i");
            RosterItemElement rosterItem2 = new RosterItemElement("i");

            rosterItem1.AddGroups("g1", "g2");
            rosterItem2.AddGroups("g1", "g2");

            Assert.That(rosterItem1, Is.EqualTo(rosterItem2));
        }

        [Test]
        public void Equals_DifferentGroupSet_ReturnsFalse()
        {
            RosterItemElement rosterItem1 = new RosterItemElement("i");
            RosterItemElement rosterItem2 = new RosterItemElement("i");

            rosterItem1.AddGroups("g1", "g2");
            rosterItem2.AddGroups("g3", "g4");

            Assert.That(rosterItem1, Is.Not.EqualTo(rosterItem2));
        }

        #endregion
    }
}
